home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Communications / PPPMonitor1.16 / Source / ExecScrollText.m < prev    next >
Text File  |  1996-01-29  |  9KB  |  322 lines

  1. // -------------------------------------------------------------------------------------
  2. // ExecScrollText.m
  3. // (Indent:4, Tabs:4)
  4. // -------------------------------------------------------------------------------------
  5. // Copyright 1996 Persistent Technologies, Inc. - all rights reserved
  6. // -------------------------------------------------------------------------------------
  7. // This source code comes with no warranty of any kind, and the user assumes all 
  8. // responsibility for its use.
  9. // -------------------------------------------------------------------------------------
  10. #import <appkit/appkit.h>
  11. #import <libc.h>
  12. #import <mach/cthreads.h>
  13. #import <stdlib.h>
  14. #import <stdarg.h>
  15. #import <string.h>
  16. #import <pwd.h>
  17. #import <sys/types.h>
  18. #import <sys/wait.h>
  19. #import "ExecScrollText.h"
  20.  
  21. // -------------------------------------------------------------------------------------
  22. // null text attribute structure
  23. static NXColor            nullColor = { 0 };
  24. static textAttr_t        nullAttr = { (id)nil, 0 };
  25. #define    isNullAttr(X)    (!X.fontId && !X.colorMode)
  26.  
  27. // -------------------------------------------------------------------------------------
  28. // Object notified when command completes
  29.  
  30. /* ExecScrollText delegate */
  31. @interface Object(ExecScrollText_Delegate)
  32. - (void)monitorOutput:scrollId buffer:(const char*)buffer len:(int)len;
  33. @end
  34.  
  35. // -------------------------------------------------------------------------------------
  36. // ExecScrollText private methods
  37. @interface ExecScrollText(Private)
  38. - _setTextAttrFont:fontId color:(int)mode:(NXColor)color;
  39. - (BOOL)_appendTextToView:(const char*)buffer len:(int)len attr:(textAttr_t)tAttr;
  40. - _appendTextAndMakeVisible:(const char*)buffer attr:(textAttr_t)tAttr;
  41. @end
  42.  
  43. // -------------------------------------------------------------------------------------
  44. /* convert color to gray */
  45. static float cvtColor2Gray(NXColor color)
  46. {
  47.     float    gray;
  48.     NXConvertColorToGray(color, &gray);
  49.     return gray;
  50. }
  51.  
  52. // -------------------------------------------------------------------------------------
  53. @implementation ExecScrollText
  54.  
  55. // -------------------------------------------------------------------------------------
  56.  
  57. /* init */
  58. - initExecScrollText:(id)anObject
  59. {
  60.     [super init];
  61.     scrollView  = anObject;
  62.     textView    = [scrollView docView];
  63.     wasEditable = [textView isEditable];
  64.     autoLf      = NO;
  65.     runAttr     = nullAttr;
  66.     //[textView setEditable:NO];
  67.     //[textView setMonoFont:NO];
  68.     return self;
  69. }
  70.  
  71. /* initializes the outlet (to be executed by main thread only!) */
  72. + newExecScrollText:(id)anObject
  73. {
  74.     return [[self alloc] initExecScrollText:anObject];
  75. }
  76.  
  77. /* return textView id (docView) */
  78. - docView
  79. {
  80.     return textView;
  81. }
  82.  
  83. /* return scroll view */
  84. - scrollView
  85. {
  86.     return scrollView;
  87. }
  88.  
  89. /* set delegate */
  90. - setDelegate:(id)theDelegate
  91. {
  92.     delegate = theDelegate;
  93.     return self;
  94. }
  95.  
  96. /* return delegate */
  97. - (id)delegate
  98. {
  99.     return delegate;
  100. }
  101.  
  102. /* set auto linefeed mode */
  103. - setAutoLineFeed:(BOOL)mode
  104. {
  105.     autoLf = mode;
  106.     return self;
  107. }
  108.  
  109. /* free object */
  110. - free
  111. {
  112.     // all pending commands should be killed here
  113.     return [super free];
  114. }
  115.  
  116. // --------------------------------------------------------------------------------
  117.  
  118. /* set font */
  119. - _setTextAttrFont:fontId color:(int)mode:(NXColor)color
  120. {
  121.     textAttr_t    tAttr = nullAttr;
  122.     tAttr.fontId    = fontId;
  123.     tAttr.colorMode    = mode;
  124.     tAttr.color        = color;
  125.     [self _appendTextAndMakeVisible:(char*)nil attr:tAttr];
  126.     return self;
  127. }
  128.  
  129. /* set font */
  130. - setTextAttributeFont:fontId
  131. {
  132.     return [self _setTextAttrFont:fontId color:0:nullColor];
  133. }
  134.  
  135. // --------------------------------------------------------------------------------
  136.  
  137. /* set gray */
  138. - setTextAttributeGray:(float)aGray
  139. {
  140.     return [self _setTextAttrFont:(id)nil color:1:NXConvertGrayToColor(aGray)];
  141. }
  142.  
  143. /* set gray */
  144. - setTextAttributeColor:(NXColor)aColor
  145. {
  146.     return [self _setTextAttrFont:(id)nil color:2:aColor];
  147. }
  148.  
  149. // --------------------------------------------------------------------------------
  150.  
  151. /* set default tabs */
  152. - setTabStops:(float*)tabArray count:(int)c
  153. {
  154.     NXTextStyle    style = *((NXTextStyle*)[textView defaultParaStyle]);
  155.     style.numTabs = (short)c;
  156.     style.tabs = (NXTabStop*)malloc(sizeof(NXTabStop) * style.numTabs);
  157.     while (--c >= 0) { style.tabs[c].kind = NX_LEFTTAB; style.tabs[c].x = tabArray[c]; }
  158.     [textView setParaStyle:(void*)&style];
  159.     return self;
  160. }
  161.  
  162. /* repeat given tab multiple times */
  163. - setTab:(float)tabSize count:(int)c
  164. {
  165.     int            i;
  166.     NXTextStyle    style = *((NXTextStyle*)[textView defaultParaStyle]);
  167.     style.numTabs = (short)c;
  168.     style.tabs = (NXTabStop*)malloc(sizeof(NXTabStop) * style.numTabs);
  169.     for (i = 0; i < c; i++) {
  170.         style.tabs[i].kind = NX_LEFTTAB;
  171.         style.tabs[i].x = (float)(i + 1) * tabSize;
  172.     }
  173.     [textView setParaStyle:(void*)&style];
  174.     return self;
  175. }
  176.  
  177. // --------------------------------------------------------------------------------
  178.  
  179. /* clear text scroll view area */
  180. - clearScrollText
  181. {
  182.     [textView setEditable:YES];
  183.     [textView setText:""];
  184.     if (!wasEditable) [textView setEditable:NO];
  185.     [scrollView display];
  186.     return self;
  187. }
  188. - clear:sender
  189. {
  190.     return [self clearScrollText];
  191. }
  192.     
  193. // --------------------------------------------------------------------------------
  194. // append text to scroll view
  195.  
  196. /* append buffer to view: return YES if text was visible */
  197. - (BOOL)_appendTextToView:(const char*)buffer len:(int)len attr:(textAttr_t)tAttr
  198. {
  199.     int        txtLen;
  200.     NXSelPt    startPt, endPt;
  201.     NXRect    rect;
  202.     
  203.     /* check for font/gray change (save state) */
  204.     if (tAttr.fontId) {
  205.         runAttr.fontId = tAttr.fontId;
  206.     }
  207.     if (tAttr.colorMode) {
  208.         runAttr.colorMode = tAttr.colorMode;
  209.         runAttr.color = tAttr.color;
  210.     }
  211.     if (!buffer || !*buffer || (len == 0)) return NO;
  212.     
  213.     /* get ready to print text */
  214.     [textView getVisibleRect:&rect];                      // visible rectangle
  215.     [textView setEditable:YES];
  216.     txtLen = [textView textLength];
  217.     [textView setSel:txtLen :txtLen];
  218.     [textView getSel:&startPt :&endPt];                   // selected coordinates
  219.  
  220.     /* set text run attributes if specified */
  221.     if (!isNullAttr(runAttr)) {
  222.         if ([textView isMonoFont]) [textView setMonoFont:NO];
  223.         if (!txtLen) { [textView replaceSel:" "]; [textView setSel:0 :1]; }
  224.         if (runAttr.fontId) [textView setSelFont:runAttr.fontId];
  225.         if (runAttr.colorMode == 1) [textView setSelGray:cvtColor2Gray(runAttr.color)];
  226.         else
  227.         if (runAttr.colorMode == 2) [textView setSelColor:runAttr.color];
  228.         runAttr = nullAttr;
  229.     }
  230.     
  231.     /* print text */
  232.     if (len > 0) [textView replaceSel:buffer length:len];
  233.     else [textView replaceSel:buffer];
  234.     if (!wasEditable) [textView setEditable:NO];
  235.  
  236.     /* delegate monitor of text written to textview */
  237.     if (delegate && [delegate respondsTo:@selector(monitorOutput:buffer:len:)]) {
  238.         [delegate monitorOutput:self buffer:buffer len:len];
  239.     }
  240.     
  241.     return (rect.origin.y + rect.size.height > endPt.y);  // was visible?
  242. }
  243.  
  244. /* append text to view and scroll to visible */
  245. - _appendTextAndMakeVisible:(const char*)buffer attr:(textAttr_t)tAttr
  246. {
  247.     BOOL    wasVisible;
  248.   
  249.     /* print buffer */
  250.     wasVisible = [self _appendTextToView:buffer len:-1 attr:tAttr];
  251.     if (autoLf && buffer) [self _appendTextToView:"\n" len:-1 attr:nullAttr];
  252.     if (wasVisible) [textView scrollSelToVisible];
  253.   
  254.     return self;
  255. }
  256.  
  257. // --------------------------------------------------------------------------------
  258. // append a formatted text string message into a text view
  259.  
  260. /* append text unformatted */
  261. - (int)textPrint:(const char*)buffer
  262. {
  263.     [self _appendTextAndMakeVisible:buffer attr:nullAttr];
  264.     return strlen(buffer);
  265. }
  266.  
  267. /* append text with variable args into textView */
  268. - (int)textPrintf:(const char*)fmt args:(va_list)args
  269. {
  270.     char    tempString[textStringSIZE] = { 0 };
  271.     int        retVal = vsprintf(tempString, fmt, args);
  272.     [self _appendTextAndMakeVisible:tempString attr:nullAttr];
  273.     return retVal;
  274. }
  275.  
  276. /* append text with variable args into textView */
  277. - (int)textPrintf:(const char*)fmt, ...
  278. {
  279.     va_list        args;
  280.     int            retVal;
  281.     va_start(args, fmt);
  282.     retVal = [self textPrintf:fmt args:args];     
  283.     va_end(args);
  284.     return retVal;
  285. }
  286.  
  287. // --------------------------------------------------------------------------------
  288. // executing commands within a shell, using the scroll text as output
  289.  
  290. /* execute a command */
  291. - (ExecRunCommand*)runCommand:(const char*)command user:(const char*)user
  292. {
  293.     return [ExecRunCommand runCommand:command user:user output:self];
  294. }
  295.  
  296. /* execute a command (don't return until it's finished) */
  297. - (int)system:(const char*)command user:(const char*)user
  298. {
  299.     return [ExecRunCommand system:command user:user output:self];
  300. }
  301.  
  302. /* command output call-back */
  303. - (void)commandOutput:(id)execId buffer:(const char*)buffer len:(int)len
  304. {
  305.     if (delegate && [delegate respondsTo:@selector(commandOutput:buffer:len:)]) {
  306.         [delegate commandOutput:execId buffer:buffer len:len];
  307.     }
  308.     if ([self _appendTextToView:buffer len:len attr:nullAttr]) {
  309.         [textView scrollSelToVisible];
  310.     }
  311. }
  312.  
  313. /* command completion call-back */
  314. - (void)commandDidComplete:(id)execId withError:(int)errorCode
  315. {
  316.     if (delegate && [delegate respondsTo:@selector(commandDidComplete:withError:)]) {
  317.         [delegate commandDidComplete:execId withError:errorCode];
  318.     }
  319. }
  320.  
  321. @end
  322.